"""Program to track daily tasks
By Joe Tannenbaum
pylint-approved!
(unless you count the 'too many statements' or 'too many branches' junk ew)

The main issue here:
Currently an empty string must be at task_list[0] to make the file work with
I/O to the .txt. Reading the code is easy enough with [1:]'s everywhere if
you know why they're there (that's why) but one must be careful adding to this
code. All task dictionaries are in task_list[1:].The smiley face I'd use to
describe this situation? 1:

"""

import os

TASKFILE = 'tasklist.txt'
OPTIONS_STRING = """
Options: 'add [task text]' to add an item to the list
         'remove [task number]' to remove an item to the list
         'did [task number]' to mark an item as done
         'undo' to undo the previous action (only if it was marking an item as done)
         'help' to display these options
         task file is saved automatically and reloads when this program starts
         NOTE: statuses of each task are not saved"""

def rw_data(task_list=None):
    """Converts/writes task_list to TASKFILE, returns what used to be in TASKFILE"""
    old_data = None
    try:
        tfile = open(TASKFILE,'r')
        old_data = tfile.read()
        tfile.close()
    except IOError:
        pass
    if task_list:
        data = '\n'.join([task['text'] for task in task_list[1:]])
        tfile = open(TASKFILE,'w')
        tfile.write(data)
    tfile.close()
    return old_data

def new_task(text):
    """Creates a new task with done as false"""
    return {'text' : text, 'done' : False}

def longest_text_len(tlist):
    """Blah blah blah tired of these"""
    max_len = 0
    for task in tlist[1:]:
        length = len(task['text'])
        if length > max_len:
            max_len = length
    return max_len

def main():
    """Main method (pylint wanted a docstring here...)"""
    tasks_raw = rw_data()
    raw_lines = tasks_raw.strip().split('\n')
    task_list = [''] + [new_task(text) for text in raw_lines if text.strip()]

    message = ''
    lastop = None
    show_options = True
    while(True):
        os.system('clear')
        ## generate display
        print '[Tasks]'
        print '+' + '-'*(longest_text_len(task_list[1:])+5)
        for idex, task in enumerate(task_list[1:]):
            outstring = ''
            outstring += str(idex + 1)
            outstring += ' [' + {True : 'C', False : ' '}[task['done']]
            outstring += '] ' + task['text']
            print outstring
        print
        if show_options:
            print OPTIONS_STRING
            print
            show_options = False
        print message

        ## take input
        indata = raw_input('>> ')
        if indata.startswith('did ') or indata.startswith('done '):
            indata = indata[4:].strip()
            if indata.isdigit():
                task_idex = int(indata) - 1
                if task_idex < len(task_list[1:]):
                    task_list[1:][task_idex]['done'] = True
                    lastop = indata
                    message = 'Marked task ' + indata + ' as done'
                else:
                    message = "That's not a valid task number"
            else:
                message = "That's not a vaild number at all!"
        elif indata.startswith('add '):
            indata = indata[4:].strip()
            task_list.append(new_task(indata))
            rw_data(task_list)
            lastop = None
            message = 'Added task: ' + indata
        elif indata.startswith('remove '):
            indata = indata[7:].strip()
            if indata.isdigit():
                task_idex = int(indata) - 1
                if task_idex < len(task_list[1:]):
                    removed_task = task_list.pop(1 + task_idex)
                    rw_data(task_list)
                    lastop = None
                    message = 'Removed task: ' + removed_task['text']
                else:
                    message = "That's not a valid task number"
            else:
                message = "That's not a vaild number at all!"
        elif indata.strip() == 'undo':
            if lastop and lastop.isdigit():
                task_list[1:][int(lastop) - 1]['done'] = False
                message = 'Undid completion'
            else:
                message = 'Nothing to undo'
        elif indata.strip() == 'help':
            show_options = True
            message = ''
        elif indata.strip() == 'quit':
            quit()
        elif indata.strip():
            message = 'Invalid entry'

if __name__ == '__main__':
    main()
